package com.paishen.common.okhttp;

import com.squareup.okhttp.MediaType;
import com.squareup.okhttp.RequestBody;

import java.io.IOException;

import okio.Buffer;
import okio.BufferedSink;
import okio.ForwardingSink;
import okio.Okio;
import okio.Sink;

/**
 * https://github.com/lizhangqu/CoreProgress
 */
public class OkProgressRequestBody extends RequestBody {
	private final RequestBody requestBody;
	private final OkCallbackAdapter<?> okCallbackAdapter;
	private BufferedSink bufferedSink;

	public OkProgressRequestBody(RequestBody requestBody, OkCallbackAdapter<?> okCallbackAdapter) {
		this.requestBody = requestBody;
		this.okCallbackAdapter = okCallbackAdapter;
	}

	@Override
	public MediaType contentType() {
		return requestBody.contentType();
	}

	@Override
	public long contentLength() throws IOException {
		return requestBody.contentLength();
	}

	@Override
	public void writeTo(BufferedSink sink) throws IOException {
		if (bufferedSink == null) {
			bufferedSink = Okio.buffer(sink(sink));
		}
		requestBody.writeTo(bufferedSink);
		bufferedSink.flush();
	}

	private Sink sink(Sink sink) {
		return new ForwardingSink(sink) {
			// 当前写入字节数
			long bytesWritten = 0L;
			// 总字节长度，避免多次调用contentLength()方法
			long contentLength = 0L;

			@Override
			public void write(Buffer source, long byteCount) throws IOException {
				super.write(source, byteCount);
				if (contentLength == 0) {
					// 获得contentLength的值，后续不再调用
					contentLength = contentLength();
				}
				// 增加当前写入的字节数
				bytesWritten += byteCount;
				// 回调
				if (okCallbackAdapter != null) {
					okCallbackAdapter.onProgress(bytesWritten, contentLength, bytesWritten == contentLength);
				}
			}
		};
	}
}